package vip.meeet.generate;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import vip.meeet.elasticsearch.DocHelper;
import vip.meeet.elasticsearch.MappingHelper;
import vip.meeet.supplier.SupplierFactory;

import java.io.IOException;
import java.util.*;
import java.util.function.Supplier;

public class ESTypeGenerator {

    private static final Map<String,Supplier> typeSupplierMap = new HashMap<>();

    public static final SupplierFactory.IntegerSupplier INTEGER_SUPPLIER = new SupplierFactory.IntegerSupplier(1000);

    static {
        typeSupplierMap.put("text", SupplierFactory.ENGLISH_NAME_SUPPLIER);
        typeSupplierMap.put("keyword",SupplierFactory.ENGLISH_NAME_SUPPLIER);
        typeSupplierMap.put("integer",INTEGER_SUPPLIER);
        typeSupplierMap.put("byte",SupplierFactory.BYTE_SUPPLIER);
        typeSupplierMap.put("short",SupplierFactory.SHORT_SUPPLIER);
        typeSupplierMap.put("long",SupplierFactory.LONG_SUPPLIER);
        typeSupplierMap.put("date",SupplierFactory.LONG_SUPPLIER);
        typeSupplierMap.put("float",SupplierFactory.FLOAT_SUPPLIER);
        typeSupplierMap.put("doule",SupplierFactory.FLOAT_SUPPLIER);
        typeSupplierMap.put("half_float",SupplierFactory.FLOAT_SUPPLIER);
        typeSupplierMap.put("scaled_float",SupplierFactory.FLOAT_SUPPLIER);
        typeSupplierMap.put("boolean",SupplierFactory.BOOLEAN_SUPPLIER);
    }

    /**
     *
     * @param hostPort
     * @param index
     * @param idPor
     * @param propertieSupplierMap
     * @param size
     * @throws IOException
     */
    public static void fillData(String hostPort,String index,String idPor,Map<String,Supplier> propertieSupplierMap,int size) throws IOException {
        List<JSONObject> docs = getDocs(hostPort,index, propertieSupplierMap, size);
        for(JSONObject doc : docs){
            DocHelper.addDoc(hostPort,index,doc.getString(idPor),doc.toJSONString());
        }
    }

    public static List<JSONObject> getDocs(String hostPort,String index,Map<String,Supplier> propertieSupplierMap,int size) throws IOException {
        String esPropertiesJson = getEsPropertiesJson(hostPort, index);
        List<JSONObject> docs = getEsDocJsonFromEsProperties(esPropertiesJson, propertieSupplierMap, size);
        return docs;
    }

    /**
     *  从ES服务器获取对应index的properties josn
     * @param hostPort
     * @param index
     * @return
     * @throws IOException
     */
    public static String getEsPropertiesJson(String hostPort,String index) throws IOException {
        String mapping = MappingHelper.getMapping(hostPort, index);
        JSONObject jsonObject = JSON.parseObject(mapping);
        JSONObject indexJson = jsonObject.getJSONObject(index);
        JSONObject mappingsJson = indexJson.getJSONObject("mappings");
        JSONObject propertiesJson = mappingsJson.getJSONObject("properties");
        return propertiesJson.toJSONString();
    }

    public static List<JSONObject> getEsDocJsonFromEsProperties(String esPropertiesJson,int size){
        return getEsDocJsonFromEsProperties(esPropertiesJson,null,size);
    }

    public static List<JSONObject> getEsDocJsonFromEsProperties(String esPropertiesJson,Map<String,Supplier> propertieSupplierMap,int size){
        if(propertieSupplierMap == null){
            propertieSupplierMap = typeSupplierMap;
        }
        JSONObject properties = JSON.parseObject(esPropertiesJson);
        Set<String> keys = properties.keySet();
        LinkedList<JSONObject> results = new LinkedList<>();
        for(int i=0;i<size;i++){
            JSONObject jsonObject = new JSONObject();
            for(String key : keys){
                JSONObject med = properties.getJSONObject(key);
                String type = med.getString("type");
                if(StringUtils.isBlank(type) || type.equalsIgnoreCase("nested")){//暂时不支持递归类型
                    continue;
                }
                Supplier supplier = propertieSupplierMap.getOrDefault(key,getSupplier(key,type));
                if(supplier == null){
                    continue;//暂时不支持的类型,object binary array ip geo_point
                }
                jsonObject.put(key,supplier.get());
            }
            results.add(jsonObject);
        }
        return results;
    }

    private static Supplier getSupplier(String propertie,String type){
        String lowerCasePropertie = propertie.toLowerCase();
        if(type.equalsIgnoreCase("text") || type.equalsIgnoreCase("keyword")){
            if(lowerCasePropertie.contains("uid")) {
                return SupplierFactory.UUID_SUPPLIER;
            }if(lowerCasePropertie.contains("id")){
                return SupplierFactory.NUMBER_ID_STRING_SUPPLIER;
            }
        }
        if(type.equalsIgnoreCase("integer") && (lowerCasePropertie.contains("date") || lowerCasePropertie.contains("time"))){
            return SupplierFactory.INTEGER_DATE_SUPPLIER;
        }
        return typeSupplierMap.get(type);
    }

}
